﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using reactiveBT.BT;
using reactiveBT.Utilities;

namespace reactiveBT.Serialization
{
    public class BTSerializer
    {
        public static void ReadJson<T>(string file, out T obj)
        {
            //Debug.Log(file);
            JsonSerializer serializer = new JsonSerializer();
            using (StreamReader sr = new StreamReader(ConstDefine.TreeFolderPath + file))
            {
                obj = JsonConvert.DeserializeObject<T>(sr.ReadToEnd(), new JsonNodeConverter());
            }
        }
    }
}
public abstract class JCreationConverter<T> : JsonConverter
{
    protected abstract T Create(Type objectType, JObject jsonObject);
    public override bool CanConvert(Type objectType)
    {
        return typeof(T).IsAssignableFrom(objectType);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var jsonObject = JObject.Load(reader);
        var target = Create(objectType, jsonObject);
        serializer.Populate(jsonObject.CreateReader(), target);
        return target;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}
public class JsonNodeConverter : JCreationConverter<BTNode>
{
    protected override BTNode Create(Type objectType, JObject jsonObject)
    {
        //获取类型名
        var typeName = jsonObject["NodeType"].ToString();
        //确认节点类型存在
        if(!Nodefactory.NodeCreators.ContainsKey(typeName))
        {
            throw new Exception("未经注册的节点类型");
        }
        //去除无效的节点信息
        jsonObject.Remove("nodeName");
        jsonObject.Remove("remark");
        jsonObject.Remove("NodeType");
        BTNode[] nodes = null;
        bool isBranch = false;
        if(jsonObject.ContainsKey("ChildNodes"))
        {
            isBranch = true;
            nodes = new BTNode[jsonObject["ChildNodes"].Count()];
            int i = 0;
            foreach (var item in jsonObject["ChildNodes"])
            {
                nodes[i] = Create(objectType, item as JObject);
            }
            jsonObject.Remove("ChildNodes");
        }
        else if(jsonObject.ContainsKey("ChildNode"))
        {
            isBranch = true;
            nodes = new BTNode[1];
            nodes[0] = Create(objectType, jsonObject["ChildNode"] as JObject);
            jsonObject.Remove("ChildNode");
        }
        var newNode = Nodefactory.NodeCreators[typeName](jsonObject);
        if(isBranch)
        {
            newNode = (newNode as Branch).OpenBranch(nodes);
        }
        return newNode;
    }
}
